package com.example.Controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.example.Req.BatchContentReq;
import com.example.Req.FcapNoContentReq;
import com.example.common.Pagination;
import com.example.common.ResponseModel;
import com.example.model.FcapNoContent;
import com.example.service.FcapNoContentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

@RestController
@Slf4j
public class FcapNoContentController {
    @Autowired
    FcapNoContentService fcapNoContentService;

    @PostMapping("/api/blog/selectByContentPage.do")
    public ResponseModel<Pagination<FcapNoContent>> selectByContentPage(@RequestBody FcapNoContentReq req) {
        ResponseModel<Pagination<FcapNoContent>> result = new ResponseModel<>();
        log.info("selectByContent param:{}", JSON.toJSONString(req));
        if (req.getPageNo() == null) {
            req.setPageNo(1);
        }
        if (req.getPageSize() == null) {
            req.setPageSize(10);
        }
        if (req != null && StringUtils.isNotBlank(req.getContent())) {
            if (req.getContent().contains(".")) {
                log.info("**************************");
                String aa = req.getContent().replace(".", "#");
                log.info("aa:" + aa);

                String[] arr = aa.split("#");
                if (arr.length < 2 ) {
                    Pagination<FcapNoContent> page = new Pagination<FcapNoContent>(req.getPageNo(), req.getPageSize(), 0);
                    page.setList(new ArrayList<FcapNoContent>());
                    result.setData(page);
                    return result;
                }
            } else {
                Pagination<FcapNoContent> page = new Pagination<FcapNoContent>(req.getPageNo(), req.getPageSize(), 0);
                page.setList(new ArrayList<FcapNoContent>());
                result.setData(page);
                return result;
            }
        }

        Pagination<FcapNoContent> page = fcapNoContentService.selectByContent(req.getContent(), req.getPageNo(), req.getPageSize());
        result.setData(page);
        log.info("result:{}", JSON.toJSONString(result));
        return result;
    }

    @PostMapping("/api/blog/insertOrUpdateFcapNoContent.do")
    public ResponseModel<Object> insertOrUpdateFcapNoContent(@RequestBody FcapNoContent fcapNoContent) {
        ResponseModel<Object> result = new ResponseModel<>();
        log.info("insertOrUpdateFcapNoContent param:{}", JSON.toJSONString(fcapNoContent));
        if (fcapNoContent == null || StringUtils.isBlank(fcapNoContent.getContent()) || StringUtils.isBlank(fcapNoContent.getNo())) {
            result.setCode("00000001");
            result.setMsg("参数为空");
            return result;
        }
        fcapNoContentService.insertOrUpdateFcapNoContent(fcapNoContent);
        return result;
    }

    @PostMapping("/api/blog/deleteFcapNoContent.do")
    public ResponseModel<Object> deleteFcapNoContent(@RequestBody FcapNoContent fcapNoContent) {
        ResponseModel<Object> result = new ResponseModel<>();
        log.info("deleteFcapNoContent param:{}", JSON.toJSONString(fcapNoContent));
        if (fcapNoContent == null || fcapNoContent.getId() == null) {
            result.setCode("00000001");
            result.setMsg("参数为空");
            return result;
        }
        fcapNoContentService.deleteFcapNoContent(fcapNoContent.getId());
        return result;
    }


    @PostMapping("/api/blog/upload")
    public ResponseModel<Object> upload(MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException {

        log.info("开始上传了。。。。");
        EasyExcel.read(file.getInputStream(), FcapNoContent.class, new ReadListener<FcapNoContent>() {
            /**
             * 单次缓存的数据量
             */
            public static final int BATCH_COUNT = 100;
            /**
             *临时存储
             */
            private List<FcapNoContent> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

            @Override
            public void invoke(FcapNoContent data, AnalysisContext context) {
                if(StringUtils.isBlank(data.getNo()) || StringUtils.isBlank(data.getContent())){
                    log.info("excel 数据错误，跳过处理");
                    return;
                }
                cachedDataList.add(data);
                if (cachedDataList.size() >= BATCH_COUNT) {
                    saveData();
                    // 存储完成清理 list
                    cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                saveData();
            }

            /**
             * 加上存储数据库
             */
            private void saveData() {
                log.info("{}条数据，开始存储数据库！", cachedDataList.size());
                fcapNoContentService.batchInsertFcapNoContent(cachedDataList);
                log.info("存储数据库成功！");
            }
        }).sheet().doRead();
        ResponseModel<Object> result = new ResponseModel<>();
        return result;
    }

    @PostMapping("/api/blog/download")
    public void download(HttpServletRequest request, HttpServletResponse response) {
        log.info("开始下载。。。。");
        /*ClassPathResource classPathResource = new ClassPathResource("template/excel_template.xlsx");
        InputStream fis = null;
        OutputStream toClient = null;
        try{
            fis = classPathResource.getInputStream();
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String("excel_template.xlsx".getBytes(), "UTF-8"));
            toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream;charset=UTF-8");
            toClient.write(buffer);
            toClient.flush();

        }catch (Exception e){

        }finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(toClient != null){
                try {
                    toClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }*/

        ClassPathResource classPathResource = new ClassPathResource("template/excel_template.xlsx");
        InputStream fis = null;
        OutputStream toClient = null;
        try{
            fis = classPathResource.getInputStream();
            XSSFWorkbook workbook = new XSSFWorkbook(fis);
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-disposition", "attachment; filename="+ new String("excel_template.xlsx".getBytes(), "UTF-8"));
            ServletOutputStream out = null;
            out = response.getOutputStream();
            workbook.write(out);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭文件输出流
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @PostMapping("/api/blog/selectByMultiContentPage.do")
    public ResponseModel<Pagination<FcapNoContent>> selectByMultiContentPage(@RequestBody BatchContentReq req) {
        ResponseModel<Pagination<FcapNoContent>> result = new ResponseModel<>();
        log.info("selectByContent param:{}", JSON.toJSONString(req));
        if (req.getPageNo() == null) {
            req.setPageNo(1);
        }
        if (req.getPageSize() == null) {
            req.setPageSize(10);
        }



        if (req == null || CollectionUtils.isEmpty(req.getList())) {
                Pagination<FcapNoContent> page = new Pagination<FcapNoContent>(req.getPageNo(), req.getPageSize(), 0);
                page.setList(new ArrayList<FcapNoContent>());
                result.setData(page);
                return result;
        }

        if (req.getRepeatStart() == null && req.getRepeatEnd() != null) {
            req.setRepeatStart(req.getRepeatEnd());
        }

        if(req.getRepeatStart() == null && req.getRepeatEnd() == null){
            req.setRepeatStart(req.getList().size());
            req.setRepeatEnd(req.getList().size());
        }

        Pagination<FcapNoContent> page = fcapNoContentService.selectByMultiContentPage(req);
        result.setData(page);
        log.info("result:{}", JSON.toJSONString(result));
        return result;
    }

    @PostMapping("/api/blog/selectByMultiContentHanziPage.do")
    public ResponseModel<Pagination<FcapNoContent>> selectByMultiContentHanziPage(@RequestBody BatchContentReq req) {
        ResponseModel<Pagination<FcapNoContent>> result = new ResponseModel<>();
        log.info("selectByContent param:{}", JSON.toJSONString(req));
        if (req.getPageNo() == null) {
            req.setPageNo(1);
        }
        if (req.getPageSize() == null) {
            req.setPageSize(10);
        }



        if (req == null || CollectionUtils.isEmpty(req.getList())) {
            Pagination<FcapNoContent> page = new Pagination<FcapNoContent>(req.getPageNo(), req.getPageSize(), 0);
            page.setList(new ArrayList<FcapNoContent>());
            result.setData(page);
            return result;
        }

        if (req.getErrorStart() == null && req.getErrorEnd() != null) {
            req.setErrorStart(req.getErrorEnd());
        }

        if(req.getErrorStart() == null && req.getErrorEnd() == null){
            req.setErrorStart(req.getList().size());
            req.setErrorEnd(req.getList().size());
        }

        Pagination<FcapNoContent> page = fcapNoContentService.selectByMultiContentHanziPage(req);
        result.setData(page);
        log.info("result:{}", JSON.toJSONString(result));
        return result;
    }
}